package com.dude.screens;

import java.io.File;
import java.util.ArrayList;

import com.dude.R;
import com.dude.interfaces.IMemoryService;
import com.dude.objects.GenericPair;
import com.dude.objects.ImageAndTextArrayAdapter;
import com.dude.utils.DialogsLibrary;
import com.dude.utils.FilesOperations;


import android.app.Activity;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;


/** this Activity should display to the user all the information about the selected single object.
 *  it is possible to edit existing profiles / add new profile through it. 
 */
public class ExtendedSingleProfile extends Activity {
	
	//============== global variables =====================
	protected boolean objectHasName=false;
	protected boolean existingProfile = false;	
	protected String name= null;
	protected IMemoryService fo = null;
	protected DialogsLibrary dl = null;
	protected ArrayList<String> commentsList = null;
	protected ArrayAdapter<String> commentsArrayAdapter = null;
	protected ArrayList<GenericPair<String, Bitmap>> imagesList = null;
	protected ArrayAdapter<GenericPair<String, Bitmap>> imagesArrayAdapter = null;
	
	
	//=================== widgets==============
	protected TextView objectName;
	protected Button addCommentBtn;
	protected Button addSoundBtn;
	protected Button deleteBtn;
	protected Button doneBtn;	
	protected Button addPicBtn;	
	protected ImageView image;
	protected ImageView playSoundBtn;
	protected ListView commentsListView;
	protected ListView imagesListView;
	protected CheckBox defaultSoundChk;

	//===============constants===================
	public static final int REQUEST_CODE_CAMERA = 100;
	public static final int REQUEST_CODE_GALLERY = 150;
	public static final int REQUEST_CODE_RECORD = 200; 
	
	public String newImagePath=null;
	private MediaPlayer mp;
	
		
    @Override
    public void onCreate(Bundle savedInstanceState) {   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.extended_single_profile);             
        
        // initialize DialogsLibrary variable
        dl = new DialogsLibrary(ExtendedSingleProfile.this, true);        
        // create and check FilesOperation object
        fo = new FilesOperations(this);       
        
        //==================== organize layout of objects' name==================
        objectName = (TextView)findViewById(R.id.objectName);          
        // check if reached this activity from create new profile
        Intent intent = getIntent();        
        boolean isNew = intent.getBooleanExtra(Profiles.isNewProfile, false);
        // if not a new profile, find out the name
        if (!isNew) //showing an existing profile
        {
        	objectHasName=true;
        	existingProfile= true;
        	name = intent.getStringExtra(Profiles.profileName);
        	objectName.setText(name);
        }
        
        objectName.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View view) {
				// set up name changing Dialog
				final GenericPair<String, Boolean> gp = new GenericPair<String, Boolean>();					
				Dialog dialog = dl.createNameDialog(objectHasName, existingProfile, name, fo, gp);				
				dialog.setOnDismissListener(new DialogInterface.OnDismissListener(){
					public void onDismiss(DialogInterface dialog) {						
						if (gp.getSecond())
						{							
							name = gp.getFirst();
							objectName.setText(gp.getFirst());
							objectHasName = true;
							existingProfile = true;
						}						
					}					
				});				
				dialog.show();
			}      	
        });
 
        //==================== organize layout of objects' picture - ========================
        //======================only if object already has name and folder in memory=========
        // show the list of images
        imagesListView = (ListView)findViewById(R.id.single_object_photos_list);
        if (existingProfile)
        	imagesList = fo.getAllPictures(name, true);
        else 
        	imagesList = new ArrayList<GenericPair<String,Bitmap>>();
        	
        imagesArrayAdapter = new ImageAndTextArrayAdapter(ExtendedSingleProfile.this, imagesList);
        imagesListView.setAdapter(imagesArrayAdapter);
        imagesListView.setOnItemClickListener(new OnItemClickListener(){
    	public void onItemClick(AdapterView<?> parent, View view, int position, long id){				
    			//get the selected picture's name
    	        String imageName = imagesList.get(position).getFirst();
    	        Bitmap bitmap = imagesList.get(position).getSecond();
    	        editPictureDialog(imageName, bitmap, position);	                        
    		}			 
    	});
        	
        
        // put the image's' list in the correct size
        ScreensUtility.setListViewHeightBasedOnChildren(imagesListView);
        
        // configure button to open dialog that enables capturing a picture
        addPicBtn = (Button)findViewById(R.id.add_photo_button_id);
        addPicBtn.setOnClickListener(new OnClickListener(){
			public void onClick(View v) {
				// open appropriate dialog box
				if (existingProfile)
				{
					if (!fo.hasMaxNumOfPictures(name))
						addPictureDialog();
					else
						dl.createOperationDeniedDialog("Object already has the maximum allowed number of pictures");						
				}					
				else
					dl.createOperationDeniedDialog("No Name Was Given For The Object. Please name the object, then try again. ");
			}           			
    	});
        
        
        //===================organize sounds' layout=================================
        addSoundBtn = (Button) findViewById(R.id.object_add_sound_button_id);
        addSoundBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent recordIntent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); 
                startActivityForResult(recordIntent, REQUEST_CODE_RECORD); 
			}
		});
        
        playSoundBtn = (ImageView) findViewById(R.id.play_sound__button_id);
        playSoundBtn.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) 
			{
				if (!defaultSoundChk.isChecked())
				{					
					String path = fo.getSoundPath(name);				
					if (path != null)
						playSoundFromPath(path);
					else
					{
						dl.createErrorDialog("no valid sound found please record sound to use");
					}
				}					
				else
					playSoundFromPath(null);
			}
		});
        
        defaultSoundChk = (CheckBox) findViewById(R.id.use_sound_checkbox);
        if (name != null)
        {
        	int res = fo.getUsesDefaultSound(name);
        	defaultSoundChk.setChecked(res == 1);
        }

        else
        	defaultSoundChk.setChecked(true);
        
        defaultSoundChk.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			
			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
			{
				fo.setUsesDefaultSound(name, isChecked);
				addSoundBtn.setEnabled(!isChecked);
				
				if (mp != null)
				{
					mp.release();
					mp = null;
				}
			}
		});
        
        addSoundBtn.setEnabled(!defaultSoundChk.isChecked());
        
        
        //==================== organize layout of objects' comments==================       
        commentsListView = (ListView)findViewById(R.id.single_object_comments_list);
        if (existingProfile){
        	commentsList = fo.getAllCommentsForObject(name, true);
        	if (commentsList==null){
            	dl.createErrorDialog("Retrieving Comments For Object Failed ");
            	// close the Activity:
            	ExtendedSingleProfile.this.finish();
        	}
        }
        else{
        	commentsList = new ArrayList<String>();
        }      
     
       commentsArrayAdapter = new ArrayAdapter<String>(this, R.layout.comments_list_item, commentsList);      
       commentsListView.setAdapter(commentsArrayAdapter);         
       commentsListView.setOnItemClickListener(new OnItemClickListener(){
			 public void onItemClick(AdapterView<?> parent, View view, int position, long id){	
				 //get the selected item
	             String comment = ((TextView) view).getText().toString();	             
	             //Launching Dialog on selecting single List Item
	             dl.editCommentDialog(name, fo, commentsList, commentsArrayAdapter, comment, position, commentsListView);
			 }			 
		 });
       
       // put the comments' list in the correct size
       ScreensUtility.setListViewHeightBasedOnChildren(commentsListView);
             
        addCommentBtn = (Button)findViewById(R.id.object_add_comment_button_id);
        addCommentBtn.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View view) {
				// set up name changing Dialog
		    	if (!objectHasName)
		    		dl.createOperationDeniedDialog("No Name Was Given For The Object. Please name the object, then try again. ");
		    	else		    	
		    		 dl.AddCommentDialog(name, fo, commentsList, commentsArrayAdapter, commentsListView);		    	
			}      	
        });
        
        //==================== set listeners to buttons================== 
    	deleteBtn = (Button)findViewById(R.id.delete_object_button_id);
    	deleteBtn.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View view) {
				dl.deleteObjectDialog(name, fo);
			}      	
        });
    	doneBtn = (Button)findViewById(R.id.done_object_button_id);
    	doneBtn.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View view) {
				// go back to previous screen
				ExtendedSingleProfile.this.finish();
			}      	
        });   	
        
    }
 
    
    
    //=======================================================================================
    //========================== methods for the various Dialog: ============================
    //=======================================================================================
     
    protected String prepareTempPicturePath()
    {
    	if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
    		return null;
    	File dir = Environment.getExternalStorageDirectory();
    	File tmpFile = new File(dir, "tmpPicture.jpg");
    	return tmpFile.getAbsolutePath();
    }
    
    
    /* the method displays a dialog that enables the user to take a picture of an object that
     * doesn't have a picture yet
     */
    protected void addPictureDialog()
    {
    	AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	builder.setTitle("Add A Picture ");
    	builder.setMessage(" You have two options for the source of the picture: take a picture of the object with the camera or add a picture from the gallery. ");
    	builder.setCancelable(true);
    	builder.setPositiveButton(" Use Camera ", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog,int id) {
				Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE );				
				newImagePath = prepareTempPicturePath();				
				if (newImagePath==null)				
				{
					dl.createErrorDialog("Cannot take Picture");
					dialog.dismiss();
					return;
				}
				intent.putExtra( MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(newImagePath)));
				startActivityForResult( intent, REQUEST_CODE_CAMERA );				
				dialog.cancel();	
			}
		  });
    	builder.setNeutralButton("Use Gallery", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog,int id) {
				Intent intent = new Intent(Intent.ACTION_PICK);
				intent.setType("image/*");
				startActivityForResult(intent, REQUEST_CODE_GALLERY);   
				dialog.cancel();			
			}
		  });
    	builder.setNegativeButton(" Cancel ", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog,int id) {
				dialog.cancel();			
			}
		  });
    	
    	//create the dialog
    	AlertDialog dialog = builder.create();
    	dialog.show(); 
    }
    
  
    
    
    /* the method returns a dialog asking the user if he wants to replace existing picture
     * with a new one
     */
    protected void editPictureDialog(final String picName, Bitmap bitmap, final int posInList)
    {
    	//create the dialog
    	final Dialog dialog = new Dialog(this);    	
    	dialog.setContentView(R.layout.edit_picture_dialog);
		dialog.setTitle(" Edit Picture ");
		dialog.setCancelable(true);
		
		// prepare the text fields
		final EditText editText = (EditText)dialog.findViewById(R.id.pic_name_ET);
		editText.setHint(picName);
							
		//prepare the buttons - cancel and edit		
		Button saveButton = (Button)dialog.findViewById(R.id.edit_pic_name_btn_id);
		Button deleteButton = (Button)dialog.findViewById(R.id.deleteButtonId);
		Button cancelButton = (Button)dialog.findViewById(R.id.cancelButtonId);
		saveButton.setOnClickListener(new OnClickListener(){
				public void onClick(View v) {					
					String newName = editText.getText().toString();					
					int result = fo.renamePicture(name, picName, newName);
					if (result ==3)
					{
						dl.createErrorDialog("Renaming Picture Failed");
						dialog.dismiss();
						return;
					}
					if (result==2)
					{
						dl.createOperationDeniedDialog("Renaming picture denied - another picture already has the same name");
						dialog.dismiss();
						return;						
					}
				 
					// update imagesList
					imagesList.get(posInList).setFirst(newName);
					imagesArrayAdapter.notifyDataSetChanged();									
					dialog.dismiss();
				}				
		 });
		
		deleteButton.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				if (!fo.removeImage(name, picName))
				{
					dl.createErrorDialog("Deleting Picture Failed");
					dialog.dismiss();
				}
				// update imagesList
				imagesList.remove(posInList);
				imagesArrayAdapter.notifyDataSetChanged();
				dialog.dismiss();						
			}				
	 });
			
		 cancelButton.setOnClickListener(new OnClickListener(){
				@Override
				public void onClick(View v) {
					dialog.dismiss();						
				}				
		 });
		 
    	dialog.show();
    }
    
    
    
    //=======================================================================================
    //========================== additional methods: ============================
    //=======================================================================================
    
    
    /* this method is called as a result of call for startActivityForResult
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    {  	
    	if ((requestCode==REQUEST_CODE_CAMERA)&&(resultCode==RESULT_OK))
    	{ 
    		 // get the image from the temporary file
    		 Bitmap bitmap = BitmapFactory.decodeFile(newImagePath);   		 
    		 // add image to object's file
    		 String picName = fo.addImage(name, bitmap);
    		 if (picName==null)
    		 {
    			 dl.createErrorDialog("Take Picture Failed");
    			 return;
    		 }
    		 // delete the temporary file
    		 File f = new File(newImagePath);
    		 f.delete();

    		 // // update imagesList - add the minimized photo to the object's profile
    		 Bitmap pic  = ThumbnailUtils.extractThumbnail(bitmap, fo.getThumbnailSize(), fo.getThumbnailSize());
     		 imagesList.add(new GenericPair<String, Bitmap>(picName, pic));    		
 			 imagesArrayAdapter.notifyDataSetChanged();	
 			 ScreensUtility.setListViewHeightBasedOnChildren(imagesListView);
    	}
    	
    	else if(requestCode == REQUEST_CODE_RECORD && resultCode == RESULT_OK)
    	{
    		String path = getRealPathFromURI(data.getData());
    		fo.setSoundPath(name, path);
    	}
    	else if (requestCode == REQUEST_CODE_GALLERY && resultCode==RESULT_OK)
    	{
            Uri uri = data.getData();
            String imageGalleryPath = getRealPathFromURI(uri);
            String imageName = fo.addPictureFromPath(name, imageGalleryPath);
            if (imageName==null)
            {
   			 	dl.createErrorDialog("Take Picture Failed");
   			 	return;           	
            }
            // add thumnbnail image to profile 
            Bitmap image = BitmapFactory.decodeFile(imageGalleryPath);
   		 	// update imagesList - add the minimized photo to the object's profile
   		 	Bitmap pic  = ThumbnailUtils.extractThumbnail(image, fo.getThumbnailSize(), fo.getThumbnailSize());
    		imagesList.add(new GenericPair<String, Bitmap>(imageName, pic));    		
			imagesArrayAdapter.notifyDataSetChanged();	
			ScreensUtility.setListViewHeightBasedOnChildren(imagesListView);
    	}
    }
    
    
    
    public String getRealPathFromURI(Uri contentUri)
    { 
        String[] proj = { MediaStore.Images.Media.DATA }; 
        Cursor cursor = managedQuery(contentUri, proj, null, null, null); 
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
        cursor.moveToFirst(); 
        return cursor.getString(column_index); 
    } 
    
    
    private void playSoundFromPath(String path)
    {
    	if (mp == null)
    	{
    		if (path != null)
    			mp = MediaPlayer.create(this, Uri.parse(path));
        	else
        		mp = MediaPlayer.create(this, R.raw.sound);
    	}
    	
    	mp.start();
    }
    

    
    @Override
    public void onDestroy()
    {
    	if (mp!= null)
    	{
    		mp.release();
    		mp = null;
    	}
    	
    	super.onDestroy();
    }
    
}

   